#include "loader.h"

#include "mmu.h"
#include "tss.h"
#include "klib.h"
#include "gdt.h"
#include "i386.h"


extern unsigned int * page_dir;



void cargar_tarea(unsigned int desde, unsigned int indice) {

	char * cod_usuario3_1 = (char *) pagina_libre_usuario();			
	char * cod_usuario3_2 = (char *) pagina_libre_usuario();		
	unsigned int * pila3 = pagina_libre_usuario();				

	unsigned int * dir_usuario = inicializar_dir_usuario();	
	unsigned int * pila0 = pagina_libre_kernel();				// esp0

	// Mapear las paginas
	mapear_pagina(0x00000000, (unsigned int) dir_usuario, (unsigned int) cod_usuario3_1, 7);
	mapear_pagina(TAMANO_PAGINA, (unsigned int) dir_usuario, (unsigned int) cod_usuario3_2, 7);
 	mapear_pagina((unsigned int) pila3, (unsigned int) dir_usuario, (unsigned int) pila3, 7);
 	mapear_pagina((unsigned int) pila0, (unsigned int) dir_usuario, (unsigned int) pila0, 3);

	//  Copiar el codigo a la nueva pagina de usuario
	unsigned int i;
	char * byte_codigo = (char *) desde;
	for (i = 0; i < TAMANO_PAGINA; i++) {
		cod_usuario3_1[i] = byte_codigo[i];		
		cod_usuario3_2[i] = byte_codigo[i+TAMANO_PAGINA];		
	}


	// Inicializar el TSS
	
	//Pilas
	tsss[indice].esp0 = (unsigned int) pila0 + TAMANO_PAGINA;
	tsss[indice].ss0  = 0x10;
	tsss[indice].unused0 = 0;
	tsss[indice].esp1 = 0;
	tsss[indice].ss1  = 0;	
	tsss[indice].unused1 = 0;
	tsss[indice].esp2 = 0;
	tsss[indice].ss2  = 0;	
	tsss[indice].unused2 = 0;	
	
	

	// MMU
	tsss[indice].cr3 = (unsigned int) dir_usuario;
	
	// Registros
	tsss[indice].eip = 0 ;// <---es direccion logica     es direccion fisica ---> (unsigned int) cod_usuario3_1;
	tsss[indice].eflags = 0x00000202;
	tsss[indice].eax = 0;
	tsss[indice].ecx = 0;
	tsss[indice].edx = 0;
	tsss[indice].ebx = 0;
	tsss[indice].esp = (unsigned int) pila3 + TAMANO_PAGINA;
	tsss[indice].ebp = (unsigned int) pila3 + TAMANO_PAGINA;
	tsss[indice].esi = 0;
	tsss[indice].edi = 0;
	tsss[indice].es = 0x28 | 3;
	tsss[indice].unused4 = 0;
	tsss[indice].cs = 0x20 | 3;
	tsss[indice].unused5 = 0;
	tsss[indice].ss = 0x28 | 3;
	tsss[indice].unused6 = 0;
	tsss[indice].ds = 0x28 | 3; /// ????
	tsss[indice].unused7 = 0;
	tsss[indice].fs = 0x28 | 3;
	tsss[indice].unused8 = 0;
	tsss[indice].gs = 0x28 | 3;
	tsss[indice].unused9 = 0;
	
	tsss[indice].ldt = 0;
	tsss[indice].unused10 = 0;
	tsss[indice].dtrap = 0x0000;
	tsss[indice].iomap = 0xFFFF;

	unsigned int indice_tss = 6+indice;
	gdt[indice_tss] = (gdt_entry) {	(unsigned short) 0x0067,
									(unsigned short) ((unsigned int) &tsss[indice] & 0xFFFF),
									(unsigned char) ((unsigned int)&tsss[indice] >> 16 ) & 0xFF,
									0x9,
									0,
									0,
									1,
									0x0,
									0x0,
									(unsigned char) ((unsigned int)&tsss[indice] >> 24 ) & 0xFF					
								   };
	
}

